// Copyright Epic Games, Inc. All Rights Reserved.

#include "LyraConfirmationScreen.h"

#if WITH_EDITOR
#include "CommonInputSettings.h"
#include "Editor/WidgetCompilerLog.h"
#endif

#include "CommonBorder.h"
#include "CommonRichTextBlock.h"
#include "CommonTextBlock.h"
#include "Components/DynamicEntryBox.h"
#include "ICommonInputModule.h"
#include "LyraButtonBase.h"

#include UE_INLINE_GENERATED_CPP_BY_NAME(LyraConfirmationScreen)

/**
 * 设置对话框内容
 * @param Descriptor 对话框描述符
 * @param ResultCallback 结果回调委托
 */
void ULyraConfirmationScreen::SetupDialog(UCommonGameDialogDescriptor* Descriptor, FCommonMessagingResultDelegate ResultCallback)
{
	// 调用父类设置
	Super::SetupDialog(Descriptor, ResultCallback);

	// 设置标题文本
	Text_Title->SetText(Descriptor->Header);
	// 设置描述富文本
	RichText_Description->SetText(Descriptor->Body);

	// 重置按钮入口框，清除所有现有按钮的点击事件
	EntryBox_Buttons->Reset<ULyraButtonBase>([](ULyraButtonBase& Button)
	{
		Button.OnClicked().Clear();
	});

	// 遍历描述符中的每个按钮动作
	for (const FConfirmationDialogAction& Action : Descriptor->ButtonActions)
	{
		// 定义数据表行句柄
		FDataTableRowHandle ActionRow;

		// 根据动作结果选择对应的输入动作
		switch(Action.Result)
		{
			case ECommonMessagingResult::Confirmed:
				// 使用默认确认点击动作
				ActionRow = ICommonInputModule::GetSettings().GetDefaultClickAction();
				break;
			case ECommonMessagingResult::Declined:
				// 使用默认返回动作
				ActionRow = ICommonInputModule::GetSettings().GetDefaultBackAction();
				break;
			case ECommonMessagingResult::Cancelled:
				// 使用取消动作
				ActionRow = CancelAction;
				break;
			default:
				// 确保不会执行到默认情况
				ensure(false);
				continue;
		}

		// 创建Lyra按钮作为入口
		ULyraButtonBase* Button = EntryBox_Buttons->CreateEntry<ULyraButtonBase>();
		// 设置触发输入动作
		Button->SetTriggeringInputAction(ActionRow);
		// 绑定点击事件到关闭确认窗口函数
		Button->OnClicked().AddUObject(this, &ThisClass::CloseConfirmationWindow, Action.Result);
		// 设置按钮文本
		Button->SetButtonText(Action.OptionalDisplayText);
	}

	// 保存结果回调委托
	OnResultCallback = ResultCallback;
}

/**
 * 关闭并销毁对话框
 */
void ULyraConfirmationScreen::KillDialog()
{
	// 调用父类实现
	Super::KillDialog();
}

/**
 * 本地初始化完成时调用
 * 绑定点击关闭区域的事件
 */
void ULyraConfirmationScreen::NativeOnInitialized()
{
	// 调用父类实现
	Super::NativeOnInitialized();

	// 绑定点击关闭区域的鼠标按下事件
	Border_TapToCloseZone->OnMouseButtonDownEvent.BindDynamic(this, &ULyraConfirmationScreen::HandleTapToCloseZoneMouseButtonDown);
}

/**
 * 关闭确认窗口
 * @param Result 关闭结果
 */
void ULyraConfirmationScreen::CloseConfirmationWindow(ECommonMessagingResult Result)
{
	// 停用控件
	DeactivateWidget();
	// 执行结果回调
	OnResultCallback.ExecuteIfBound(Result);
}

/**
 * 处理点击关闭区域的鼠标按钮按下事件
 * @param MyGeometry 控件几何信息
 * @param MouseEvent 鼠标事件
 * @return 事件回复
 */
FEventReply ULyraConfirmationScreen::HandleTapToCloseZoneMouseButtonDown(FGeometry MyGeometry, const FPointerEvent& MouseEvent)
{
	// 定义事件回复
	FEventReply Reply;
	// 默认设置为未处理
	Reply.NativeReply = FReply::Unhandled();

	// 如果是触摸事件或者左键按下事件
	if (MouseEvent.IsTouchEvent() || MouseEvent.GetEffectingButton() == EKeys::LeftMouseButton)
	{
		// 关闭确认窗口，结果为拒绝
		CloseConfirmationWindow(ECommonMessagingResult::Declined);
		// 标记为已处理
		Reply.NativeReply = FReply::Handled();
	}

	// 返回事件回复
	return Reply;
}

#if WITH_EDITOR
/**
 * 验证编译时的默认值
 * @param CompileLog 编译器日志接口
 */
void ULyraConfirmationScreen::ValidateCompiledDefaults(IWidgetCompilerLog& CompileLog) const
{
	// 检查取消动作是否未设置
	if (CancelAction.IsNull())
	{
		// 记录错误日志
		CompileLog.Error(FText::Format(FText::FromString(TEXT("{0} has unset property: CancelAction.")), FText::FromString(GetName())));
	}
}
#endif